import tkinter as tk
from tkinter import font as tkfont
from user_client_socket import TcpSocket
from tkinter import messagebox as msgbox
import json
from setting import *
# effbot.org


# 主页页面, 进行了页面的初始化设置,设置其他页面的时候需要继承该页面
class IndexPage:
    def __init__(self,  width=750, height=450, page_name='Page_1'):

        self.width = width
        self.height = height
        self.pname = page_name
        self.window = tk.Tk()
        self.font = tkfont.Font(family='宋体', size=12, weight='normal')
        tkfont.Font()
        self.scree_size = '%dx%d+%d+%d' % (self.width, self.height, (self.window.winfo_screenwidth() - width) / 2,
                                           (self.window.winfo_screenheight() - height) / 2)
        self.window.geometry(self.scree_size)
        self.window.title(self.pname)
        self.us = TcpSocket()
        # self.cur = mysql()

        self.uname = '6666'
        self.pwd = ''

    def get_window(self):
        return self.window

    def create_page(self):
        # 用户名
        tk.Label(self.window, text='用户名：', font=self.font
                 ).place(x=int(self.width) * 0.25, y=int(self.height) * 0.25)
        # 密码
        tk.Label(self.window, text='密  码：', font=self.font
                 ).place(x=int(self.width) * 0.25, y=int(self.height) * 0.45)

        self.entry_uname = tk.Entry(self.window, font=self.font, width=30)
        self.entry_uname.bind('<Return>', self.keyboard_login)
        self.entry_uname.place(x=int(self.width) * 0.35, y=int(self.height) * 0.25)

        # 密码的输入框
        self.entry_pwd = tk.Entry(self.window, font=self.font, width=30, show='*')
        self.entry_pwd.bind('<Return>', self.keyboard_login)
        self.entry_pwd.place(x=int(self.width) * 0.35, y=int(self.height) * 0.45)
        tk.Button(self.window,
                  text='登录',
                  command=self.do_login,
                  font=self.font
                  ).place(x=int(self.width) * 0.30, y=int(self.height) * 0.65)

        tk.Button(self.window,
                  text='注册',
                  command=self.do_regist,
                  font=self.font
                  ).place(x=int(self.width) * 0.60, y=int(self.height) * 0.65)

        tk.Button(self.window,
                  text='忘记密码',
                  command=self.do_find_pwd,
                  height=1,
                  font=self.font
                  ).place(x=int(self.width) * 0.65, y=int(self.height) * 0.55)

        self.window.mainloop()

    def do_find_pwd(self):
        self.window.destroy()
        first_find_page = FindPwdStepFirst()
        first_find_page.create_page()

    def do_regist(self):
        self.window.destroy()
        regist_page = RegistUser()
        regist_page.create_page()

    def keyboard_login(self, event):
        print(event)
        self.do_login()

    def do_login(self):
        # 获取用户名密码，然后去服务端对比，ok的话就quit这个然后打开新的页面
        self.uname = self.entry_uname.get()
        self.pwd = self.entry_pwd.get()

        user_info_accept_msg = 'GET /login?user_name=%s&passwd=%s HTTP/1.1' % (self.uname, self.pwd)
        self.us.send_to_server(user_info_accept_msg)
        recv_status = self.us.recv_from_server().split(':')
        # if self.uname == '':
        #     recv_status = ('200',)

        if recv_status[0] == '200':
            self.window.destroy()  # 这里只能用destroy,用quit()的话主界面就退不出去
            self.user_id = recv_status[2]
            home_page = HomePage(self.uname, self.user_id)
            home_page.create_page()

        elif recv_status[0] == '404':
            print(recv_status[0])

        else:
            print('什么都没有匹配到')


# 用户信息页面
class UserInfoPage(IndexPage):
    def __init__(self, user_name, user_id):
        super().__init__()
        self.uname = user_name
        self.uid = user_id

    def create_page(self):
        # 页面元素构建
        self.window.title('我是用户信息页面')
        tk.Button(self.window, text='返回到主页', command=self.do_return_home_page, font=self.font
                  ).pack(anchor='sw')
        # 左侧用户信息==========================================================
        frame_left = tk.Frame(self.window, bg='white')
        tk.Label(frame_left, text='=用户信息=', anchor='n', bg='white', font=self.font
                 ).pack(anchor='n', fill=tk.X)

        frame_user_name = tk.Frame(frame_left, bg='green', height=self.height*0.25)
        frame_user_email = tk.Frame(frame_left, bg='yellow', height=self.height*0.25)
        frame_user_amount = tk.Frame(frame_left, bg='blue', height=self.height*0.25)
        frame_user_info = tk.Frame(frame_left, bg='red', height=self.height*0.25)

        # tk.Label(frame_user_name, text='UserName:123').pack()

        frame_user_name.pack(anchor='s', fill=tk.X)
        frame_user_email.pack(anchor='s', fill=tk.X)
        frame_user_amount.pack(anchor='s', fill=tk.X)
        frame_user_info.pack(anchor='s', fill=tk.X)
        frame_left.place(relx=0, rely=0, relwidth=.5, relheight=1)

        # 右侧约课信息==========================================================
        # 生成滚动条件
        frame_right = tk.Frame(self.window, bg='white')

        sb_x = tk.Scrollbar(frame_right, orient=tk.HORIZONTAL)
        sb_y = tk.Scrollbar(frame_right)

        tk.Label(frame_right, text='=约课信息=', background='white', anchor='n', font=self.font).pack(anchor='n', fill=tk.X)

        # 约课的信息的列表,通过frame把滚动条和列表封装在一起了，但是不知道为什么框架的大小会自适应列表的大小
        lb = tk.Listbox(frame_right, height=self.height,
                        yscrollcommand=sb_y.set,
                        xscrollcommand=sb_x.set,
                        font=self.font)

        self.us.send_to_server('GET /orderlist/sorderinfo?stu_id=%s socket' % self.uid)
        coder, stu_order_info_json = stu = self.us.recv_from_server().split(';')

        if coder == '200':
            stu_order_info = json.loads(stu_order_info_json)
            index = 0

            for info in stu_order_info:
                lb.insert(index, '开课时间:%s点  课程名称: %s  任课教师: %s  课程简介: %s'
                          % (info['class_time'], info['class_name'], info['teacher_name'], info['class_info']))
                index += 1
        else:
            pass

        lb.pack(fill=tk.BOTH)
        sb_x.pack(side='bottom', fill=tk.X, before=lb)
        sb_y.pack(side='right', fill=tk.Y, before=lb)  # 使用before属性的时候，被覆盖的属性必须也是pack进框架中的才可以
        sb_y.config(command=lb.yview)
        sb_x.config(command=lb.xview)
        frame_right.place(relx=0.5, rely=0, relwidth=0.5, relheight=1)

        # 页面开始循环
        self.window.mainloop()

    def do_return_home_page(self):
        self.window.destroy()
        home_page = BackToHome(self.uname)
        home_page.create_page()

    def class_cancel(self):
        pass
        # 监听点击时间, 取消课程



# 课程详情页面
class ClassDetail(IndexPage):
    def __init__(self, user_name):
        super().__init__()
        self.name = user_name

    def create_page(self):
        self.window. title('我是视频详情页面')
        self.window.mainloop()


# 主页面
class HomePage(IndexPage):
    def __init__(self, user_name, user_id):
        super().__init__()
        self.uname = user_name
        self.uid = user_id

    def create_page(self):
        # 页面元素构建
        print('entry_val: ', self.uname)
        self.window.title('我是主页')
        tk.Label(text=self.uname, font=self.font).place(x=int(self.width) * 0.8, y=int(self.height) * 0.1)
        tk.Button(text='跳转到是视频详情页', command=self.do_video_page, bg='white'
                  ).place(x=int(self.width) * 0.8, y=int(self.height) * 0.2)
        tk.Button(text='跳转到用户', command=self.do_user_info_page).pack(side='left')
        tk.Button(text='定课', command=self.do_class_order).pack(side='bottom')

        # 页面开始循环
        self.window.mainloop()

    def do_class_order(self):
        self.window.destroy()
        try:
            class_order = OrderPage(self.uname, self.uid)
            class_order.create_page()
        except Exception as e:
            print('课程预约页面异常, 错误原因：', e)

    def do_user_info_page(self):
        self.window.destroy()
        user_info_page = UserInfoPage(self.uname, self.uid)
        user_info_page.create_page()

    def do_video_page(self):
        self.window.destroy()
        video_page = VideoPage(self.uname)
        video_page.create_page()


# 视频详情页面
class VideoPage(IndexPage):
    def __init__(self, user_name):
        super().__init__()
        self.user_name = user_name

    def create_page(self):
        tk.Label(text='我是视频详情').pack(side='left')
        tk.Button(text='返回上一页', command=self.do_return_last_page).pack(side='right')
        self.window.mainloop()

    def do_return_last_page(self):
        self.window.destroy()
        home_page = HomePage()
        home_page.create_page()


# 注册页面
class RegistUser(IndexPage):
    def __init__(self):
        super().__init__()
        self.window.title('我是注册页面')

    def create_page(self):
        frame_1 = tk.Frame(bg='white')
        frame_center = tk.Frame(frame_1, bg='white')

        lb_name = tk.Label(frame_center, text='用户名', font=self.font)
        lb_pwd = tk.Label(frame_center, text='密码', font=self.font)
        lb_email = tk.Label(frame_center, text='邮箱', font=self.font)

        self.rg_user_name = tk.Entry(frame_center)
        self.rg_user_passwd = tk.Entry(frame_center)
        self.rg_user_email = tk.Entry(frame_center)

        b1 = tk.Button(frame_center, text='提交', command=self.done_regist)
        b2 = tk.Button(frame_center, text='返回', command=self.do_back)

        b1.pack(anchor='s')
        b2.pack(anchor='s')

        lb_name.pack(anchor='nw')
        self.rg_user_name.pack(anchor='nw')
        lb_pwd.pack(anchor='w')
        self.rg_user_passwd.pack(anchor='w')
        lb_email.pack(anchor='sw')
        self.rg_user_email.pack(anchor='sw')

        frame_center.place(relx=0, rely=.2, relwidth=1, relheight=0.5)
        frame_1.place(relx=.32, rely=0, relwidth=.35, relheight=1)
        self.window.mainloop()

    def done_regist(self):
        regist_request = 'GET /regist?user_name=%s&passwd=%s&email=%s socket' % (
            self.rg_user_name.get(), self.rg_user_passwd.get(), self.rg_user_email.get())

        self.us.send_to_server(regist_request)
        regist_msg = self.us.recv_from_server().split(':')
        print(regist_msg)

        if regist_msg[0] == '200':
            print(regist_msg[1])
            self.window.destroy()
            index_page = IndexPage()
            index_page.create_page()
        else:
            print(regist_msg[1])

    def do_back(self):
        pass


# 找回密码第一页
class FindPwdStepFirst(IndexPage):
    def __init__(self):
        super().__init__()
        self.window.title('我是找回密码的第一个页面')

    def create_page(self):
        tk.Button(text='提交', command=self.go_find_pwd_second).pack()
        self.window.mainloop()

    def go_find_pwd_second(self):
        self.window.destroy()
        second_findpwd_page = FindPwdStepSecond()
        second_findpwd_page.create_page()


class FindPwdStepSecond(IndexPage):
    def __init__(self):
        super().__init__()
        self.window.title('我是找回密码的第二个页面')

    def create_page(self):
        tk.Button(text='提交修改', command=self.done_find_pwd).pack(side='right')
        self.window.mainloop()

    def done_find_pwd(self):
        # 判断设置的密码是否合法, 如果合法则执行下面的代码
        self.window.destroy()
        index_page = IndexPage()
        index_page.create_page()


# 回到主页时可以使用该类
class BackToHome(HomePage):
    def __init__(self, user_name):
        self.uname = user_name
        super().__init__(self.uname)

    def back_to_home(self):
        self.create_page()


# 课程预约界面
class OrderPage(IndexPage):
    def __init__(self, user_name, user_id):
        self.var = tk.StringVar
        super().__init__()
        self.uname = user_name
        self.uid = user_id

    def create_page(self):
        index = 0
        detail_info_dict = {}
        mapped_dict = {}
        get_class_id = 0

        # 两个frame
        frame_order_list = tk.Frame(self.window)
        frame_order_detail = tk.Frame(self.window, bg='green')

        # 两个listbox的操作
        order_listbox = tk.Listbox(frame_order_list, height=self.height)
        detail_listbox = tk.Listbox(frame_order_detail, height=self.height)

        def do_choice(_):
            nonlocal get_class_id
            index = 0
            detail_index = mapped_dict[order_listbox.curselection()[0]]  # 从mapped里去除索引对应的class_id映射
            detail_info_list = ['class_name', 'class_type', 'teacher_name', 'class_info', 'class_time']
            detail_desc = ['课程名称: ', '课程科目: ', '任课教师: ', '课程介绍: ', '上课时间: ']

            get_class_id = detail_index

            for detail_key in detail_info_list:
                detail_listbox.insert(index, detail_desc[index] + str(detail_info_dict[detail_index][detail_key]))
                index += 1

        order_listbox.bind('<Double-Button-1>', do_choice)

        def do_order(_, self):
            user_choice = msgbox.askquestion(title='约课确认', message='确定是否约课')

            if 'yes' == user_choice:
                self.us.send_to_server('GET /orderlist/add?stu_id=%s&class_id=%s socket' % (self.uid, get_class_id))
                rep_code, rep_msg = self.us.recv_from_server().split(':')
                if rep_code == '200':
                    msgbox.showinfo(MSGBOX_TITLE_ORDER, message='%s' % rep_msg)

                else:
                    msgbox.showinfo(MSGBOX_TITLE_ORDER, message='%s' % rep_msg)

            else:
                print('取消约课')

        detail_listbox.bind('<Double-Button-1>', lambda x: do_order(_=x, self=self))

        # 返回主页button
        tk.Button(frame_order_detail, text='回到主页', command=self.do_back).pack(anchor='ne')

        # listbox标题
        tk.Label(frame_order_list, text='').pack(side='top')
        tk.Label(frame_order_detail, text='课程详情:', font=self.font).pack(side='top')
        tk.Label(frame_order_list, text='可预约课程:', font=self.font).pack(anchor='n')

        self.us.send_to_server('GET /orderlist/info socket')
        order_page_json = self.us.recv_from_server()
        order_page_info = json.loads(order_page_json)

        order_listbox.pack(fill=tk.BOTH)
        frame_order_list.place(relx=0, rely=0, relwidth=.5, relheight=1)

        detail_listbox.pack(fill=tk.BOTH)
        frame_order_detail.place(relx=.5, rely=0, relwidth=.5, relheight=1)

        for class_info in order_page_info:
            order_listbox.insert(index, '课程: %s'
                                  % (class_info['class_name']))

            detail_info_dict[class_info['class_id']] = class_info

            mapped_dict[index] = class_info['class_id']

            index += 1

        # 打印内容，先不要删
        print(order_page_info)  # 服务器返回来的课程信息列表
        print(detail_info_dict)  # 创建的课程id 和 详细信息的映射表
        print(mapped_dict)  # listbox索引和class_id映射表

        self.window.mainloop()

    def do_back(self):
        self.window.destroy()
        home_page = HomePage(self.uname, self.uid)
        home_page.create_page()


if __name__ == '__main__':
    home = IndexPage().create_page()  # 开启主页
